#include "CRC.h"

//---------------------------------------------- myCCRC8 ---------------------
myCCRC8::myCCRC8(unsigned char Poly, bool bInvert)
{
    m_bInvert = bInvert;
    if (m_bInvert)//颠倒字节中的位
    {
        unsigned char PolyInvert = 0;
        if (Poly & 0x01) PolyInvert |= 0x80;
        if (Poly & 0x02) PolyInvert |= 0x40;
        if (Poly & 0x04) PolyInvert |= 0x20;
        if (Poly & 0x08) PolyInvert |= 0x10;
        if (Poly & 0x10) PolyInvert |= 0x08;
        if (Poly & 0x20) PolyInvert |= 0x04;
        if (Poly & 0x40) PolyInvert |= 0x02;
        if (Poly & 0x80) PolyInvert |= 0x01;
        Poly = PolyInvert;
    }
    for (int i = 0; i<256; i++)
    {
        unsigned char Data = (unsigned char)i;
        unsigned char Accum = 0;
        if (m_bInvert)
        {
            for (int j = 0; j<8; j++)
            {
                if ((Data^Accum) & 0x01) Accum = (Accum >> 1) ^ Poly;
                else Accum >>= 1;
                Data >>= 1;
            }
        }
        else
        {
            for (int j = 0; j<8; j++)
            {
                if ((Data^Accum) & 0x80) Accum = (Accum << 1) ^ Poly;
                else Accum <<= 1;
                Data <<= 1;
            }
        }
        m_Table[i] = Accum;
    }
}

void myCCRC8::CalculateCRC(unsigned char* pData, int nLength, unsigned char& CRC)
{
    unsigned char* pStop = pData + nLength;
    while (pData<pStop) CRC = m_Table[(CRC^*pData++)];
}

int myCCRC8::add(int a, int b)
{
    return a+b;
}

//---------------------------------------------- myCCRC16 ---------------------
myCCRC16::myCCRC16(unsigned short wPoly, bool bInvert)
{
    m_bInvert = bInvert;
    if (m_bInvert)
    {
        unsigned short wPolyInvert = 0;
        if (wPoly & 0x0001) wPolyInvert |= 0x8000;
        if (wPoly & 0x0002) wPolyInvert |= 0x4000;
        if (wPoly & 0x0004) wPolyInvert |= 0x2000;
        if (wPoly & 0x0008) wPolyInvert |= 0x1000;
        if (wPoly & 0x0010) wPolyInvert |= 0x0800;
        if (wPoly & 0x0020) wPolyInvert |= 0x0400;
        if (wPoly & 0x0040) wPolyInvert |= 0x0200;
        if (wPoly & 0x0080) wPolyInvert |= 0x0100;
        if (wPoly & 0x0100) wPolyInvert |= 0x0080;
        if (wPoly & 0x0200) wPolyInvert |= 0x0040;
        if (wPoly & 0x0400) wPolyInvert |= 0x0020;
        if (wPoly & 0x0800) wPolyInvert |= 0x0010;
        if (wPoly & 0x1000) wPolyInvert |= 0x0008;
        if (wPoly & 0x2000) wPolyInvert |= 0x0004;
        if (wPoly & 0x4000) wPolyInvert |= 0x0002;
        if (wPoly & 0x8000) wPolyInvert |= 0x0001;
        wPoly = wPolyInvert;
    }
    for (int i = 0; i<256; i++)
    {
        unsigned char Data = (unsigned char)i;
        unsigned short wAccum = 0;
        if (m_bInvert)
        {
            for (int j = 0; j<8; j++)
            {
                if ((Data^wAccum) & 0x0001) wAccum = (wAccum >> 1) ^ wPoly;
                else wAccum >>= 1;
                Data >>= 1;
            }
        }
        else
        {
            for (int j = 0; j<8; j++)
            {
                if ((Data^wAccum) & 0x8000) wAccum = (wAccum << 1) ^ wPoly;
                else wAccum <<= 1;
                Data <<= 1;
            }
        }
        m_wTable[i] = wAccum;
    }
}

void myCCRC16::CalculateCRC(unsigned char* pData, int nLength, unsigned short& wCRC)
{
    unsigned char* pStop = pData + nLength;
    if (m_bInvert)
    {
        while (pData<pStop) wCRC = (wCRC >> 8) ^ m_wTable[(wCRC^*pData++) & 0x00ff];
    }
    else
    {
        while (pData<pStop) wCRC = (wCRC << 8) ^ m_wTable[(wCRC^*pData++) & 0x00ff];
    }
}
